package qs.openxt.libs.plugins;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;

import qs.openxt.libs.R;
import qs.openxt.libs.fragment.ConfirmDialogListener;
import qs.openxt.libs.progress.Wait;
import qs.openxt.libs.util.ActivityUtil;

/**
 * 获取GPS
 *
 * @author 颖杰_2
 */
public class BdGpsPlugins extends CordovaPlugin {
    protected LocationManager locationManager;
    private static int GPS = 0;
    private boolean hasGps = false;

    private CallbackContext callbackContext;
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1: {
                    callbackContext.success((String) msg.obj);
                    break;
                }
                case 2: {
                    Toast.makeText(cordova.getActivity(), (String) msg.obj, Toast.LENGTH_LONG).show();
                    break;
                }
                default:
                    break;
            }
        }
    };

    private void sendMessage(int what, String mMessage) {
        Message msg = new Message();
        msg.what = what;
        msg.obj = mMessage;
        mHandler.sendMessage(msg);
    }

    private final LocationListener gpsLocationListener = new LocationListener() {

        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                case LocationProvider.AVAILABLE:
                    break;
                case LocationProvider.OUT_OF_SERVICE:
                    Wait.sharedInstance().stop();
                    break;
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Wait.sharedInstance().stop();
                    break;
            }
        }

        // Provider被enable时触发此函数，比如GPS被打开
        @Override
        public void onProviderEnabled(String provider) {

        }

        // Provider被disable时触发此函数，比如GPS被关闭
        @Override
        public void onProviderDisabled(String provider) {
            Wait.sharedInstance().stop();
        }

        //当坐标改变时触发此函数，如果Provider传进相同的坐标，它就不会被触发
        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                if (ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                Wait.sharedInstance().stop();
                locationManager.removeUpdates(networkLocationListener);
                locationManager.removeUpdates(gpsLocationListener);
                //纬度
                double latitude = location.getLatitude();
                //经度
                double longitude = location.getLongitude();

                try {
                    com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
                    json.put("longitude", longitude);
                    json.put("latitude", latitude);

                    sendMessage(1, json.toString());
                }catch (Exception e){
                }
            }
        }
    };

    private final LocationListener networkLocationListener = new LocationListener() {

        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                case LocationProvider.AVAILABLE:
                    break;
                case LocationProvider.OUT_OF_SERVICE:
                    Wait.sharedInstance().stop();
                    break;
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Wait.sharedInstance().stop();
                    break;
            }
        }

        // Provider被enable时触发此函数，比如GPS被打开
        @Override
        public void onProviderEnabled(String provider) {

        }

        // Provider被disable时触发此函数，比如GPS被关闭
        @Override
        public void onProviderDisabled(String provider) {
            Wait.sharedInstance().stop();
        }

        //当坐标改变时触发此函数，如果Provider传进相同的坐标，它就不会被触发
        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                if (ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                Wait.sharedInstance().stop();
                removeUpdates();
                //纬度
                double latitude = location.getLatitude();
                //经度
                double longitude = location.getLongitude();

                try {
                    com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
                    json.put("longitude", longitude);
                    json.put("latitude", latitude);

                    sendMessage(1, json.toString());
                }catch (Exception e){
                }
            }
        }
    };

    public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;
        if ("doBdGpsApp".equals(action)) {
            try {
                if(!ActivityUtil.isNetworkAvailable(cordova.getActivity())){
                    sendMessage(2, cordova.getActivity().getString(R.string.isNetworkAvailable));
                    return false;
                }
                boolean isForce = "true".equals(args.optString(0));
                final boolean isShowWait = "true".equals(args.optString(1));
                if(locationManager != null){
                    Wait.sharedInstance().stop();
                    removeUpdates();
                }
                locationManager = (LocationManager) cordova.getActivity().getSystemService(Context.LOCATION_SERVICE);
                //判断GPS是否正常启动
                if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                    if(isForce) {
                        sendMessage(2, "请开启GPS导航和无线导航...");
                        //返回开启GPS导航设置界面
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        cordova.startActivityForResult(BdGpsPlugins.this, intent, GPS);
                        return true;
                    }else{
                        ActivityUtil.showConfirmDialog(cordova.getActivity(), "GPS尚未开启，是否立即开启", "开启", "稍后再说", new ConfirmDialogListener() {
                            @Override
                            public void onOK() {
                                //返回开启GPS导航设置界面
                                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                cordova.startActivityForResult(BdGpsPlugins.this, intent, GPS);
                            }

                            @Override
                            public void onCancel() {
                                if(isShowWait)
                                    Wait.sharedInstance().start(cordova.getActivity(), "正在获取地理位置...，请稍候");
                                try {
                                    requestLocationUpdates();
                                }catch (Exception e){
                                    try{
                                        Wait.sharedInstance().stop();
                                        removeUpdates();
                                    }catch (Exception e1){
                                        sendMessage(2, e1.getMessage());
                                    }
                                }
                            }
                        });
                        return true;
                    }
                }

                if(isShowWait)
                    Wait.sharedInstance().start(cordova.getActivity(), "正在获取地理位置...，请稍候");
                requestLocationUpdates();
            }catch (Exception e) {
                try{
                    Wait.sharedInstance().stop();
                    removeUpdates();
                }catch (Exception e1){
                    sendMessage(2, e1.getMessage());
                }
            }
            return true;
        }
        return false;
    }

    private void requestLocationUpdates(){
        if (ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 10, gpsLocationListener);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, networkLocationListener);
    }

    private void removeUpdates(){
        if (ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        locationManager.removeUpdates(networkLocationListener);
        locationManager.removeUpdates(gpsLocationListener);
    }

    public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
    }
}
